package org.singledog.dogmail.common.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置
 *
 * @author ZheMing Liu
 * @since 2022.1.18
 */
@Configuration
public class ThreadPoolConfig {

    @Value("${thread.task.min.qps}")
    private int minQPS;

    @Value("${thread.task.max.qps}")
    private int maxQPS;

    @Value("${thread.task.cost}")
    private double cost;

    @Value("${thread.task.deadline}")
    private int deadline;

    @Bean
    public Executor registerExecutor() {
        //核心线程数，qps/(1 / 每秒线程花费时间)
        int coreSize = new Double(minQPS / (1 / cost)).intValue();
        //队列容量，(核心线程数 / 每秒线程花费时间) * 线程执行时间上限
        int queueCapacity = new Double((coreSize / cost) * deadline).intValue();
        //最大线程数 (qps - 队列容量) / (每秒线程花费时间)
        int maxSize = new Double((maxQPS - queueCapacity) / (1 / cost)).intValue();
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(coreSize);
        threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
        threadPoolTaskExecutor.setMaxPoolSize(maxSize);
        threadPoolTaskExecutor.setAllowCoreThreadTimeOut(false);
        threadPoolTaskExecutor.setThreadNamePrefix("Task-");
        threadPoolTaskExecutor.setKeepAliveSeconds(deadline);
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        return threadPoolTaskExecutor;
    }
}
